#include "genFromMemory.h"

namespace sp::Image::Gen{

void registe_genFromMemory(){
    genFromMemory::registe();
}

genFromMemory::genFromMemory(std::vector<std::string> v){ // long fps, long size, int width, int height
    assert(v.size() == 3);
    name = "genFromMemory";
    class_name = "Image-Gen-genFromMemory";
    video_ptr_head = DATA_SOURCE;
    current_video_ptr = video_ptr_head;
    fps = std::stoi(v[0]);
    size = std::stol(v[1]);
    width = std::stoi(v[2]);
    height = std::stoi(v[3]);
    index = 0;
    cnt = 1;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({},MAT));
}

genFromMemory::genFromMemory(char* video_ptr_head, long size, int fps, int width, int height){
    name = "genFromMemory";
    class_name = "Image-Gen-genFromMemory";
    this->video_ptr_head = video_ptr_head;
    this->fps = fps;
    this->size = size;
    this->width = width;
    this->height = height;
    current_video_ptr = video_ptr_head;
    index = 0;
    cnt = 1;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({},MAT));
}

genFromMemory::genFromMemory(){
    name = "genFromMemory";
    class_name = "Image-Gen-genFromMemory";
    current_video_ptr = video_ptr_head;
    index = 0;
    cnt = 1;
    data_type_support.push_back(std::pair<std::vector<uint8_t>, uint8_t>({},MAT));
}

genFromMemory::~genFromMemory(){

}

void genFromMemory::registe(){
    Function::Register("Image-Gen-genFromMemory", createObject);
    Function::Register("Image-Gen-genFromMemory", createObject2);
}

Function* genFromMemory::createObject(std::vector<std::string> params){
    return new genFromMemory(params);
}

Function* genFromMemory::createObject2(){
    return new genFromMemory();
}

void genFromMemory::start(){
    isFirst = true;
}

bool genFromMemory::waitForResource(){
    return true;
}

void genFromMemory::process(std::vector<std::vector<Data*>>& data_input, std::vector<Data*>& data_output){
    // 赋值time_start
    if(isFirst){
        gettimeofday(&time_start, NULL);
        isFirst = false;
    }
    // 验证输入个数
    assert(data_input.size() != 0);
    assert(data_input[0].size() == 1);
    // 得到图片
    for(int i = 0; i < batch_size; i++){
        if(index >= size){
            // 释放内存
            executor->free((char*)data_input[i][0]);
            data_output.push_back(DATA_END);
            break;
        }else{
            // 不进行内存的拷贝，这样可以快速测试多路视频
            // char* mat_data_ptr = executor->malloc(width, height);
            // memcpy(mat_data_ptr, current_video_ptr, height*width*3);
            current_video_ptr += height*width*3;
            data_input[i][0]->set(3, height, width, (uchar*)current_video_ptr);
            data_output.push_back(data_input[i][0]);
        }
        index++;
    }
    // 等待结束
    struct timeval t;
    gettimeofday(&t, NULL);
    double time_cost = (t.tv_sec + ((double)t.tv_usec/1000000)) - (time_start.tv_sec + ((double)time_start.tv_usec/1000000));
    while(time_cost < ((double)1.0/fps)*cnt){
        gettimeofday(&t, NULL);
        time_cost = (t.tv_sec + ((double)t.tv_usec/1000000)) - (time_start.tv_sec + ((double)time_start.tv_usec/1000000));
    }
    cnt++;
}

bool genFromMemory::releaseResource(){
    return true;
}

void genFromMemory::finish(){
    
}

void genFromMemory::copy(Function* other){
    Function::defaultCopy(other);
    genFromMemory* oth = dynamic_cast<genFromMemory*>(other);
    this->video_ptr_head = oth->video_ptr_head;
    this->fps = oth->fps;
    this->size = oth->size;
    this->width = oth->width;
    this->height = oth->height;
}

};